import os.path
import time
import re

from src.algo.selenium.ChatgptSelenium import ChatgptSelenium
from src.video.baseInfo.VideoFolderInfo import VideoFolderInfo
from src.video.baseInfo.VideoSrtInfo import VideoSrtInfo
from src.utils.text_utils import remove_non_chinese,get_check_index
from src.utils.file_utils import write_file,read_file
from src.settings import REMOVE_DIRTY_URL
from src.utils.text_filter_api import get_dirty_words,get_dirty_remove_words
import json
import random
import pysrt




def get_convert_dict(origin_lists,new_sentence):
    del_sentence = [text for text in json.loads(new_sentence)["deleted_sentences"]]

    print("###########")
    print(origin_lists)
    print(del_sentence)
    print("###########")


    convert_dict = {}
    for text in origin_lists:
        text = text.strip()
        if text == "":
            continue

        find = False
        new_text = ""
        for new_text in del_sentence:
            if new_text == "":
                continue
            if set(new_text) & set(text) == set(new_text):
                find =True
                break
        if not find:
            convert_dict[text] = text
        else:
            if new_text != text and len(text) <= len(new_text) * 0.4:
                convert_dict[text] = text.replace(new_text,"")
            else:
                convert_dict[text] = ""
    return convert_dict

def get_json_string(text):
    pattern = re.compile("\{.*\}", re.DOTALL)
    matches = pattern.findall(text)
    if matches:
        return matches[0]
    else:
        return ""

def caculate_similary(text_one,text_two):
    joinSet = set(text_one) & set(text_two)


    if len(joinSet) / len(set(text_one)) >= 0.7:
        return True
    else:
        return False



class Copywriter():
    '''
    文案改写：增加标点符号->随机删除句子->重写句子
    '''
    def __init__(self,chatgpt_url,chrome_driver_path,video_folder_info: VideoFolderInfo):
        self.init = False
        self.chatgpt_url = chatgpt_url
        self.chrome_driver_path = chrome_driver_path
        self.video_folder_info = video_folder_info


        self._init_prompt()



    def _init_prompt(self):
        self.quote_prompt = '''小说：{wenan}\n要求：把上面的[小说]内容，添加合适的标点符号，不要修改[小说]内容,不要修改文字\n输出：直接输出[小说],不要输出无关内容'''
        self.reduce_prompt = '''文案：{wenan}
    请帮我按照以下步骤删减文案：
        1.找出句子长度小于20个字符的句子。 
        2在不影响文案流畅性的情况下的删除4个句子。 
        3.并把删除的句子保存到json字符串的deleted_sentences中。
        输出格式：直接输出只包含deleted_sentences的json字符串
        '''
        self.rewrite_prompt =  '''帮我按照以下要求，重写句子：
        1.将句子中的一些[动词]、[名词]替换成其它意思[相近的动词、名词]
        2.改变[句子结构]和[语法]。
        3.更加[口语化]或者[非正式]的风格
        4.文字描述更加[生动][形象]一点
        5.删除个别[无意义]的文字
        6.重写以后的句子保持句子之间通顺
输出格式：
       重写以后的句子:[重写以后的句子]
            
句子：{wenan}
        '''

        self.remove_dirty_prompt = '''请替换句子中带侮辱性的，不道德的词语
输出格式：
    句子1:xxxx

以下是输入的句子：
{text}'''

        self.rewrite_prompt_retry = '''重写的不够好,请按以上格式重新生成一次'''
        #输入格式：确保回复的内容都是中文，并将重以后的文案放到json字符串的关键词text中，确保输出的字符串是json格式的,且json里面只有个关键词text
        self.chanslat_prompt = '''
        角色： 你现在是一个中英翻译官
        要求：请把输入的中文翻译成英文
        输出格式：
            英文1:[翻译以后的英文]
            英文2:[翻译以后的英文]
            英文3:[翻译以后的英文]
            ...
            英文N:[翻译以后的英文]

        开始
        {text}
        '''

        self.rewrite_prmpt_batch = '''
帮我按照以下要求,重写句子：
    1.将句子中的一些[动词]、[名词]替换成其它意思[相近的动词、名词]
    2.改变[句子结构]和[语法]。
    3.更加[口语化]或者[非正式]的风格
    4.文字描述更加[生动][形象]一点
    5.删除个别[无意义]的文字
    6.重写的句子不能太长
   
输出格式：
    句子1:重写以后的句子1
    句子2:重写以后的句子2
    ...
    句子N:重写以后的句子N
            
以下是输入的句子：
{text}'''

        self.short_prompt_batch = '''
帮我按照以下要求,重写句子：
    1.更加通俗易懂
    2.句子表达的意思不变
    3.句子字符更少
    4.句子里面的关键动词，名词不能变
    
输出格式：
    句子1:重写以后的句子1
    句子2:重写以后的句子2
    ...
    句子N:重写以后的句子N
            
以下是输入的句子：
{text}

输出内容:
'''
    def get_prompt_text(self,text_lists,prompt_type,is_first=1,context=""):
        prompt_str = ""
        if prompt_type == "quote":
            prompt_str = self.quote_prompt.format(wenan=" ".join(text_lists))
        elif prompt_type == 'reduce':
            prompt_str = self.reduce_prompt.format(wenan="。".join(text_lists))
        elif prompt_type == 'translate':
            text = "\n".join(["中文%s:%s" % (i+1,j) for i,j in enumerate(text_lists) ])
            prompt_str = self.chanslat_prompt.format(text=text)
        elif prompt_type == 'rewrite':
            text = "\n".join(["    句子%s:%s" % (i + 1, j) for i, j in enumerate(text_lists)])
            prompt_str = self.rewrite_prompt.format(text=text)
        elif prompt_type == 'reshort':
            text = "\n".join(["    句子%s:%s" % (i + 1, j) for i, j in enumerate(text_lists)])
            prompt_str = self.short_prompt_batch.format(text=text)

        return prompt_str

    def check_add_punctuatione_text_not_modify(self,originLists, addPunctuationText,currentMaxHitIndex,check_ignore):
        '''
        :param originLists:
        :param addPunctuationText:
        :param currentMaxHitIndex:
        :return:
        '''
        addPunctuationText = addPunctuationText.replace("【","").replace("】","").replace("文案:","").replace("文案：","")
        sentences = [s.strip() for s in re.split(r'[。？?！!]', addPunctuationText)]
        output = {}

        originIndex = 0
        newIndex = 0

        tempString = ""
        tempOrigin = ""
        hitIndexs = []
        while originIndex < len(originLists):
            if tempString == "":
                if hitIndexs:
                    output[tempOrigin] = [i + currentMaxHitIndex for i in hitIndexs]
                    hitIndexs = []
                try:
                    tempString = remove_non_chinese(sentences[newIndex])
                    tempOrigin = sentences[newIndex]
                    newIndex += 1
                except Exception as e:
                    raise e

            originTextClean = remove_non_chinese(originLists[originIndex]["origin_text"])
            originLists[originIndex]["origin_text_clean"] = originTextClean
            if originTextClean == "":
                originIndex += 1
                continue

            if len(originTextClean) > len(tempString) and newIndex < len(sentences):
                tempString += remove_non_chinese(sentences[newIndex])
                tempOrigin += "。" + sentences[newIndex]
                newIndex += 1


            joinSet = set(originTextClean) & set(tempString[:len(originTextClean)])
            print("origintText:" + originTextClean)
            print("tempString:" + tempString)
            print("###################3")

            if len(joinSet) / len(set(originTextClean)) >= 0.65:
                check_index = get_check_index(tempString,originTextClean)
                tempString = tempString[check_index+1:]
                hitIndexs.append(originIndex)
            else:
                raise ValueError("文本未找到")

            originIndex += 1
        if tempOrigin:
            output[tempOrigin] = [i + currentMaxHitIndex for i in hitIndexs]

        currentMaxHitIndex += len(originLists)
        format_output = []
        for key,value in output.items():
            item = {}
            item["origin_text"] = key
            item["origin_srt_index"] = value
            item["break"] = 0
            format_output.append(item)
        format_output[-1]["break"] = 1 if check_ignore  else 0
        return format_output, currentMaxHitIndex

    def add_punctuation(self):
        '''
        给电影文案增加标点符号
        :param text:
        :return:
        '''

        if not self.init:
            self.chatgpt_selenium = ChatgptSelenium(self.chatgpt_url, self.chrome_driver_path)

        max_sentent_len = 600

        temp_lists = []
        temp_len = 0
        output = []
        temp_result = {}
        currentIndex = 0


        if os.path.exists(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName):
            temp_result = read_file(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName)
            output = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName)

        chatgpi_count = 0
        if os.path.exists(self.video_folder_info.jieshuo_srt_remove_dirty_file):
            self.video_srt_info = VideoSrtInfo(self.video_folder_info.jieshuo_srt_remove_dirty_file)
        else:
            self.video_srt_info = VideoSrtInfo(self.video_folder_info.jieshuo_srt_clean_file)
        for index, srt_info in enumerate(self.video_srt_info.srt_infos):
            if temp_len + len(srt_info.text) > max_sentent_len or srt_info.ignore == True:
                print([i["origin_index"] for i in temp_lists])
                print(srt_info.ignore)
                temp_sens = ' '.join([i["origin_text"].strip() for i in temp_lists])
                if temp_sens and  temp_sens not in temp_result:
                    chatgpi_count += 1

                    if chatgpi_count < 100:
                        print('调用chatgpt开始:' + str(chatgpi_count))
                        response_text = self.chatgpt_selenium.get_prompt_result(
                            self.get_prompt_text([i["origin_text"] for i in temp_lists],'quote'))
                    else:
                        response_text = ""
                    if '...' in response_text:
                        response_text = response_text.replace("...", ",")
                    if '……' in response_text:
                        response_text = response_text.replace("……", ",")
                    response_text = response_text.replace("小说：","")
                    if response_text:
                        subOutput,currentIndex = self.check_add_punctuatione_text_not_modify(
                            temp_lists, response_text,temp_lists[0]["origin_index"],srt_info.ignore == True)

                        temp_result = read_file(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName)
                        output = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName,default_value=[])

                        output.extend(subOutput)
                        temp_result[temp_sens] = ""

                        write_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName,
                                   output, input_type='json')
                        write_file(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName,
                                   temp_result, input_type='json')


                temp_lists = []
                temp_len = 0
                print('调用chatgpt结束')
                time.sleep(1)

            if srt_info.text:
                info = {}
                info["origin_text"] = srt_info.text
                info["origin_index"] = srt_info.index
                temp_lists.append(info)
                temp_len += len(srt_info.text)
        if temp_lists:
            temp_sens = ' '.join([i["origin_text"] for i in temp_lists])
            if temp_sens not in temp_result:
                print('调用chatgpt开始')
                temp_result = read_file(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName)
                output = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName,default_value=[])

                response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text([i["origin_text"] for i in temp_lists],'quote'))
                subOutput,currentIndex = self.check_add_punctuatione_text_not_modify(temp_lists, response_text,currentIndex,len(temp_lists))
                print(response_text)
                output.extend(subOutput)
                temp_result[temp_sens] = ""
                write_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName, output, input_type='json')
                write_file(self.video_folder_info.jieshuoSrtAddPunctuationTempFileName, temp_result, input_type='json')

    def reduce_text(self):
        '''
        给电影文案删除部分句子
        :param text:
        :return:
        '''
        input_dict = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName, out_type='json')
        text_lists = list(input_dict.keys())

        max_sentent_len = 1000

        temp_lists = []
        temp_len = 0


        output = {}
        for text in text_lists:
            if temp_len + len(text) > max_sentent_len:
                print('调用chatgpt开始')

                response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text(temp_lists,'reduce'))

                response_json = get_json_string(response_text)
                output.update(get_convert_dict(temp_lists, response_json))

                temp_lists = []
                temp_len = 0
                print('调用chatgpt结束')
                time.sleep(8)
            temp_lists.append(text)
            temp_len += len(text)

        if temp_lists:
            print('调用chatgpt开始')
            response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text(temp_lists,'reduce'))

            response_json = get_json_string(response_text)
            output.update(get_convert_dict(temp_lists, response_json))

        write_file(self.video_folder_info.jieshuoSrtReduceTextFileName, output, input_type='json')



    def rewrite_text(self):
        if not self.init:
            self.chatgpt_selenium = ChatgptSelenium(self.chatgpt_url, self.chrome_driver_path)
        if not os.path.exists(self.video_folder_info.jieshuoSrtRewriteFileName):
            convert_list = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName, out_type='json')
            newConvertDict = []
            temp_list = []
            temp_key = ""

            for index,item in enumerate(convert_list):
                if len(item['origin_text']) >= 30:
                    if temp_list:
                        newConvertDict.append(temp_list)
                    newConvertDict.append(item)
                    temp_key = ""
                    temp_list = []
                else:
                    if temp_key:
                        temp_key += "。" + item['origin_text']
                        temp_list.append(item)

                        if len(temp_key) >= 30:
                            newConvertDict.append(temp_list)
                            temp_key = ""
                            temp_list = []
                    else:
                        temp_key = item['origin_text']
                        temp_list.append(item)
            if temp_list:
                newConvertDict.append(temp_list)


            revertConvertList = []
            for info in newConvertDict:
                if type(info) == dict:
                    info['rewrite'] = ""
                    revertConvertList.append(info)
                else:
                    newItem  = {}
                    newItem["origin_text"] = "。".join([i["origin_text"] for  i in info])
                    newItem['origin_srt_index'] = []
                    for subItem in info:
                        newItem['origin_srt_index'].extend(subItem["origin_srt_index"])
                    newItem['rewrite'] = ""
                    revertConvertList.append(newItem)

            write_file(self.video_folder_info.jieshuoSrtRewriteFileName,revertConvertList)

        output = read_file(self.video_folder_info.jieshuoSrtRewriteFileName, out_type='json')
        context = ""
        for index, item in enumerate(output):
            if item["rewrite"] == "" :
                print('调用chatgpt开始')
                rewrite_text = item["origin_text"]
                response_text = item["origin_text"]
                start = 1
                while caculate_similary(response_text,rewrite_text):
                    if start == 1:
                        response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text([response_text],'rewrite',context=context))
                        start = 0
                    else:
                        response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text([response_text], 'rewrite_retry',context=context))
                    print(response_text)
                    if response_text.startswith("重写以后的句子") or "{" not in response_text:
                        response_text = response_text.replace("重写以后的句子:", "").replace("重写以后的句子：", "").strip()
                    else:
                        response_text = json.loads(get_json_string(response_text))["text"]
                item["rewrite"] = response_text
                print('调用chatgpt结束')
                time.sleep(2)
                write_file(self.video_folder_info.jieshuoSrtRewriteFileName, output, input_type='json')

            context = item["rewrite"]

    def rewrite_batch(self,prompt_type="translate",recheck=False):
        if not os.path.exists(self.video_folder_info.jieshuoSrtRewriteFileName):
            convert_list = read_file(self.video_folder_info.jieshuoSrtAddPunctuationFileName, out_type='json')
            newConvertDict = []
            temp_list = []
            temp_key = ""

            for index,item in enumerate(convert_list):
                if len(item['origin_text']) >= 30 or ("break" in item and item['break'] == 1):
                    if temp_list:
                        newConvertDict.append(temp_list)
                    newConvertDict.append(item)
                    temp_key = ""
                    temp_list = []
                else:
                    if temp_key:
                        temp_key += "。" + item['origin_text']
                        temp_list.append(item)

                        if len(temp_key) >= 30:
                            newConvertDict.append(temp_list)
                            temp_key = ""
                            temp_list = []
                    else:
                        temp_key = item['origin_text']
                        temp_list.append(item)
            if temp_list:
                newConvertDict.append(temp_list)


            revertConvertList = []
            for info in newConvertDict:
                if type(info) == dict:
                    info['rewrite'] = ""
                    info['translate'] = ""
                    revertConvertList.append(info)
                else:
                    newItem  = {}
                    newItem["origin_text"] = "。".join([i["origin_text"] for  i in info])
                    newItem['origin_srt_index'] = []
                    for subItem in info:
                        newItem['origin_srt_index'].extend(subItem["origin_srt_index"])
                    newItem['rewrite'] = ""
                    revertConvertList.append(newItem)

            write_file(self.video_folder_info.jieshuoSrtRewriteFileName,revertConvertList)


        output = read_file(self.video_folder_info.jieshuoSrtRewriteFileName, out_type='json')
        temp_list = []

        check_key = ""
        if prompt_type == "translate":
            from_key = "origin_text"
            check_key = "translate"
        elif prompt_type == "rewrite":
            from_key = "origin_text"
            check_key = "rewrite"
        elif prompt_type == "reshort":
            from_key = "rewrite"
            check_key = 'reshort'

        for index, item in enumerate(output):
            if check_key not in item:
                item[check_key] = ""

            from_text = item[from_key].strip()
            origin_text = item["origin_text"].strip()
            if not from_text.endswith("。"):
                from_text +="。"
            if not origin_text.endswith("。"):
                origin_text +="。"

            if  "谁曾想" in origin_text:
                j = 1

            if item[check_key] == "":
                if prompt_type == "reshort":
                    if len(origin_text) <= 5 and len(from_text) > len(origin_text):
                        item[check_key] = origin_text
                    elif len(origin_text) <= 11 and len(from_text) <= len(origin_text):
                        item[check_key] = from_text
                    elif  len(origin_text) * 0.95 > len(from_text):
                        item[check_key] = from_text
                    else:
                        temp_list.append(item)
                else:
                    temp_list.append(item)
            else:
                if  prompt_type == "reshort":
                    if  len(origin_text) * 0.95 <= len(item[check_key]):
                        temp_list.append(item)

            if len(temp_list) == 8:
                if not self.init:
                    self.chatgpt_selenium = ChatgptSelenium(self.chatgpt_url, self.chrome_driver_path)
                    self.init = True

                tranlate_texts = [get_dirty_remove_words(i[from_key].replace(":",",").replace("\"","")) for i in temp_list]
                origin_texts = [i["origin_text"].replace(":",",").replace("\"","").strip() for i in temp_list]
                for index,i in enumerate(tranlate_texts):
                    if not i.endswith("。"):
                        tranlate_texts[index] = i +"。"

                for index,i in enumerate(origin_texts):
                    if not i.endswith("。"):
                        origin_texts[index] = i +"。"


                response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text(tranlate_texts,prompt_type))
                response_list = self.update_output(response_text,prompt_type,len(tranlate_texts))
                assert len(temp_list) == len(response_list)
                for i,j in zip(temp_list,response_list):
                    if prompt_type == "rewrite":
                        if recheck:
                            i[check_key] = j
                        else:
                            if not caculate_similary(i[check_key], j):
                                i[check_key] = j
                    elif prompt_type == "reshort":
                        origin_text = i["origin_text"].strip()
                        if not origin_text.endswith("。"):
                            origin_text += "。"
                        j = j.strip()
                        if j:
                            if origin_text <= 11 and len(j) <= len(origin_text):
                                i[check_key] = j
                            elif len(j) <= 0.95 * len(origin_text):
                                i[check_key] = j
                            elif len(j) < len(i[from_key]):
                                i[from_key] = j

                    else:
                        i[check_key] = j

                time.sleep(2)
                write_file(self.video_folder_info.jieshuoSrtRewriteFileName, output, input_type='json')
                temp_list = []

        if len(temp_list):
            tranlate_texts = [i[from_key] for i in temp_list]
            response_text = self.chatgpt_selenium.get_prompt_result(self.get_prompt_text(tranlate_texts, prompt_type))
            response_list = self.update_output(response_text, prompt_type,len(tranlate_texts))
            assert len(temp_list) == len(response_list)
            for i, j in zip(temp_list, response_list):
                if prompt_type == "rewrite":
                    if recheck:
                        i[check_key] = j
                    else:
                        if not caculate_similary(i[check_key], j):
                            i[check_key] = j
                elif prompt_type == "reshort":
                    origin_text = i["origin_text"].strip()
                    if not origin_text.endswith("。"):
                        origin_text += "。"
                    j = j.strip()
                    if j :
                        if len(origin_text) <= 11 and len(j)  <= len(origin_text):
                            i[check_key] = j
                        elif len(j) <= 0.95 * len(origin_text):
                            i[check_key] = j
                        elif len(j) < len(i[from_key]):
                            i[from_key] = j


                else:
                    i[check_key] = j
            time.sleep(2)
            write_file(self.video_folder_info.jieshuoSrtRewriteFileName, output, input_type='json')
            temp_list = []


    def update_output(self,responset_text,prompt_type,check_num):
        output = []
        if prompt_type == "translate":
            lines = responset_text.split("\n")
            check_items = ["英文%s:" % i for i in range(1,check_num +1) ]
            for check in check_items:
                for line in lines:
                    if check in line.strip():
                        output.append(line.strip().replace(check,""))
                        break
        elif prompt_type == "rewrite" or prompt_type == "reshort":
            lines = responset_text.split("\n")
            check_items = ["句子%s:" % i for i in range(1,check_num +1) ]
            for check in check_items:
                for line in lines:
                    if check in line.strip():
                        output.append(line.strip().replace(check,""))
                        break
        return [i.replace(" ","").replace("\t","") for i in output]


    def remove_dirty_words(self):
        if not os.path.exists(self.video_folder_info.jieshuo_srt_remove_dirty_file):
            srtInfos = pysrt.open(self.video_folder_info.jieshuo_srt_clean_file)
            temp_srt_info = []
            for index,item in enumerate(srtInfos.data):
                dirty_words_remove = get_dirty_remove_words(item.text)
                if dirty_words_remove:
                    item.text = dirty_words_remove
                #     pass
                #
                #     response_text = chatgpt_selenium.get_prompt_result(
                #         self.get_prompt_text(temp_text, "remove_dirty"))
                #     response_list = self.update_output(response_text, "remove_dirty",len(temp_srt_info))
                #     for i, j in zip(temp_srt_info, response_list):
                #         i.text = j
                #
                #     temp_srt_info = []
                # temp_srt_info.append(item)


            srtInfos.save(self.video_folder_info.jieshuo_srt_remove_dirty_file)

    def process(self):
        self.remove_dirty_words()
        self.add_punctuation()
        #self.reduce_text()
        #self.rewrite_text()
        self.rewrite_batch(prompt_type="rewrite")
        for i in range(4):
            self.rewrite_batch(prompt_type="reshort")

        #self.rewrite_batch()
